#ifndef __ICE_TRANSPORT_CHANNEL_H
#define __ICE_TRANSPORT_CHANNEL_H
#include <string>
#include <memory>
#include <rtc_base/third_party/sigslot/sigslot.h>
#include "base/event_loop.h"
#include "ice/ice_def.h"
#include "ice/port_allocator.h"
#include "ice/ice_credentials.h"
#include "ice/candidate.h"
#include "ice/stun.h"
#include "ice/ice_controller.h"
namespace xrtc
{
    class UDPPort;
    enum class IceTransportState
    {

        k_new,
        k_checking,
        k_connected,
        k_completed,
        k_failed,
        k_disconnected,
        k_closed,

    };
    class IceTransportChannel : public sigslot::has_slots<>
    {
    public:
        IceTransportChannel(EventLoop *el, PortAllocator *allocator, const std::string &_transport_name, IceCandidateComponent component);
        virtual ~IceTransportChannel();
        const std::string &transport_name() { return _transport_name; }
        IceCandidateComponent component() { return _component; }
        void gathering_candidate(); // 收集candidate
        void set_ice_params(const IceParameters &ice_params);
        void set_remote_ice_params(const IceParameters &ice_params);
        bool writable() { return _writable; }
        bool receiving() { return _receiving; }
        IceTransportState state() {return _state;}
        int send_packet(const char *data, size_t data_len);

        sigslot::signal2<IceTransportChannel *, const std::vector<Candidate> &> strsignal_candidate_allocate_done; /// signal2 其中2 代表参数格式
        sigslot::signal1<IceTransportChannel *> signal_receiving_state;
        sigslot::signal1<IceTransportChannel *> signal_writable_state;
        sigslot::signal1<IceTransportChannel *> signal_ice_state_changed;

        sigslot::signal4<IceTransportChannel *, const char *, size_t, int64_t> signal_read_packet;

        std::string to_string();

    private:
        void _on_unknown_address(UDPPort *port, const rtc::SocketAddress &addr, StunMessage *msg, const std::string &remote_ufrag);
        void _sort_connection_and_update_state();
        void _maybe_start_pinging();
        void _add_connection(IceConnection *conn);
        void _on_check_and_ping();
        void _ping_connection(IceConnection *conn);
        void _maybe_switch_selected_connection(IceConnection *conn);
        void _switch_selected_connection(IceConnection *conn);
        IceTransportState _compute_ice_transport_state();

        void _update_connection_states();
        void _update_state();
        void _set_writable(bool writable);
        void _set_receiving(bool receving);

        // 信号处理函数
        void _on_connection_destoryed(IceConnection *conn);
        void _on_connection_state_change(IceConnection *conn);
        void _on_read_packet(IceConnection * /*conn*/, const char *buf, size_t len, int64_t ts);

        friend void ice_ping_cb(EventLoop * /*el*/, TimerWatcher * /*w*/, void *data);

    private:
        EventLoop *_el;
        std::string _transport_name;
        IceCandidateComponent _component;
        PortAllocator *_allocator;

        // ice 参数信息
        IceParameters _ice_params;
        IceParameters _remote_ice_params;
        std::vector<Candidate> _local_candidates;
        std::vector<UDPPort*> _ports;
        // 连通性检测
        std::unique_ptr<IceController> _ice_controller;
        bool _start_pinging = false;
        TimerWatcher *_ping_watcher = nullptr;
        int64_t _last_ping_sent_ms = 0;
        int _cur_ping_interval = WEAK_PING_INTERVAL;
        IceConnection *_selected_connection = nullptr;
        bool _writable = false;
        bool _receiving = false;
        IceTransportState _state = IceTransportState::k_new;
        bool _had_connection = false; //是否创建过链接
        bool _has_been_connection = false;//是否成功的建立过链接（连通过）

    };

} // namespace xrtc

#endif